package com.qdhh.enrollment.security;

import cn.dev33.satoken.stp.StpUtil;
import com.qdhh.enrollment.security.annotation.RequireIdentityVerified;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * 身份认证拦截器
 * 检查需要身份认证的接口，验证 identityVerified=1
 */
@Component
public class IdentityVerificationInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 只处理方法级别的拦截
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        
        // 检查方法或类上是否有 @RequireIdentityVerified 注解
        RequireIdentityVerified annotation = handlerMethod.getMethodAnnotation(RequireIdentityVerified.class);
        if (annotation == null) {
            annotation = handlerMethod.getBeanType().getAnnotation(RequireIdentityVerified.class);
        }

        // 如果没有注解，不需要身份认证检查
        if (annotation == null) {
            return true;
        }

        // 检查是否已登录
        if (!StpUtil.isLogin()) {
            writeForbidden(response, "未登录");
            return false;
        }

        // 从 Session 中获取身份认证状态
        Object identityVerifiedObj = StpUtil.getSession().get("identityVerified");
        Integer identityVerified = identityVerifiedObj != null ? (Integer) identityVerifiedObj : 0;

        // 检查是否已认证
        if (identityVerified == null || identityVerified != 1) {
            writeForbidden(response, "需要身份认证");
            return false;
        }

        return true;
    }

    private void writeForbidden(HttpServletResponse response, String message) throws IOException {
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.getWriter().write(String.format("{\"code\":403,\"message\":\"%s\"}", message));
        response.getWriter().flush();
    }
}

